package com.linzm.leetcode.mid.exercises2_20230211;

import java.util.Arrays;

/**
 * @Author zimingl
 * @Date 2023/2/13 22:44
 * @Description: 满足条件的子序列数目
 * 给你一个整数数组 nums 和一个整数 target 。
 * 请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。
 * 由于答案可能很大，请将结果对 109 + 7 取余后返回。
 * 输入：nums = [3,5,6,7], target = 9
 * 输出：4
 * 解释：有 4 个子序列满足该条件。
 * [3] -> 最小元素 + 最大元素 <= target (3 + 3 <= 9)
 * [3,5] -> (3 + 5 <= 9)
 * [3,5,6] -> (3 + 6 <= 9)
 * [3,6] -> (3 + 6 <= 9)
 * <p>
 * 输入：nums = [3,3,6,8], target = 10
 * 输出：6
 * 解释：有 6 个子序列满足该条件。（nums 中可以有重复数字）
 * [3] , [3] , [3,3], [3,6] , [3,6] , [3,3,6]
 * <p>
 * 输入：nums = [2,3,3,4,6,7], target = 12
 * 输出：61
 * 解释：共有 63 个非空子序列，其中 2 个不满足条件（[6,7], [7]）
 * 有效序列总数为（63 - 2 = 61）
 * <p>
 * 1 <= nums.length <= 105
 * 1 <= nums[i] <= 106
 * 1 <= target <= 106
 *
 * 做法：[1, 2, 4, 8, 16, 32]
 */
public class Demo9_1498 {
    public static void main(String[] args) {
        Demo9_1498 demo9_1498 = new Demo9_1498();
        int[] nums = {2,3,3,4,6,7};
//        int[] nums = {3, 5, 6, 7};
        int target = 12;
        int numSubseq = demo9_1498.numSubseq(nums, target);
        System.out.println(numSubseq);
    }

    static int mod = 1000000007;

    private int numSubseq(int[] nums, int target) {
        Arrays.sort(nums);
        int res = 0;
        int n = nums.length;
        int[] pow = new int[n];
        pow[0] = 1;
        for (int i = 1; i < n; i++) {
            pow[i] = pow[i - 1] * 2 % mod;
        }
        int left = 0, right = n - 1;
        while (left <= right) {
            if (nums[left] + nums[right] <= target) {
                res += pow[right - left];
                res %= mod;
                left++;
            } else
                right--;
        }
        return res;
    }
}
